﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace AzureDiagMon.Common.Helpers
{
    /// <summary>
    /// ListViewColumnStretch
    /// </summary>
    public class ListViewExtensions : DependencyObject
    {
        #region Dependancy Property Infrastructure

        /// <summary>
        /// IsStretched Dependancy property which can be attached to gridview columns.
        /// </summary>
        public static readonly DependencyProperty StretchProperty =
            DependencyProperty.RegisterAttached("Stretch",
            typeof(bool),
            typeof(ListViewExtensions),
            new UIPropertyMetadata(true, null, OnCoerceStretch));


        /// <summary>
        /// Gets the stretch.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns></returns>
        public static bool GetStretch(DependencyObject obj)
        {
            return (bool)obj.GetValue(StretchProperty);
        }

        /// <summary>
        /// Sets the stretch.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <param name="value">if set to <c>true</c> [value].</param>
        public static void SetStretch(DependencyObject obj, bool value)
        {
            obj.SetValue(StretchProperty, value);
        }

        /// <summary>
        /// Called when [coerce stretch].
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static object OnCoerceStretch(DependencyObject source, object value)
        {
            var listView = (source as ListView);

            if (listView == null)
                throw new ArgumentException("This property may only be used on ListViews");

            listView.Loaded += ListViewLoaded;
            listView.SizeChanged += ListViewSizeChanged;
            return value;
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the SizeChanged event of the lv control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
        private static void ListViewSizeChanged(object sender, SizeChangedEventArgs e)
        {
            var listView = (sender as ListView);
            if (listView != null && listView.IsLoaded)
            {
                //Set our initial widths.
                SetColumnWidths(listView);
            }
        }

        /// <summary>
        /// Handles the Loaded event of the lv control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private static void ListViewLoaded(object sender, RoutedEventArgs e)
        {
            var listView = (sender as ListView);
            if (listView != null)
                SetColumnWidths(listView);
        }
        #endregion

        #region Private Members

        //TODO: Review this code 

        /// <summary>
        /// Sets the column widths.
        /// </summary>
        private static void SetColumnWidths(ListView listView)
        {
            //Pull the stretch columns fromt the tag property.
            var columns = (listView.Tag as List<GridViewColumn>);
            double specifiedWidth = 0;
            var gridView = listView.View as GridView;
            if (gridView != null)
            {
                if (columns == null)
                {
                    //Instance if its our first run.
                    columns = new List<GridViewColumn>();
                    // Get all columns with no width having been set.
                    foreach (var column in gridView.Columns)
                    {
                        if (!(column.Width >= 0))
                            columns.Add(column);
                        else specifiedWidth += column.ActualWidth;
                    }
                }
                else
                {
                    // Get all columns with no width having been set.
                    foreach (var column in gridView.Columns)
                        if (!columns.Contains(column))
                            specifiedWidth += column.ActualWidth;
                }

                // Allocate remaining space equally.
                foreach (var column in columns)
                {
                    var newWidth = (listView.ActualWidth - specifiedWidth -
                        (gridView.Columns.Count - columns.Count) * 5) / columns.Count;
                    if (newWidth >= 0)
                    {
                        column.Width = Math.Max(0,
                            newWidth - SystemParameters.VerticalScrollBarWidth);
                    }
                }

                //Store the columns in the TAG property for later use. 
                listView.Tag = columns;
            }
        }


        #endregion
    }
}
